package scuba.DiveBuddy.Class;

import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.joda.time.Period;
import scuba.DiveBuddy.Core.RDPCalculator;
import scuba.DiveBuddy.Core.Toolbelt;
import scuba.DiveBuddy.data.LogEntrySource;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;

/**
 * Created by Alexander Anderson on 22/02/14.
 */
public class LogEntries {

    //Singleton
    private static LogEntries _instance;
    public static LogEntries getInstance() {
        if(_instance == null)
            _instance = new LogEntries();

        return _instance;
    }
    public static LogEntry getCurrent() {
        return getInstance().getCurrentLog();
    }
    public static void setCurrent(LogEntry entry) {
        getInstance().Current = entry;
    }


    private ArrayList<LogEntry> _Collection;
    private boolean isCacheValid;
    private LogEntry Current;


    //ctor
    public LogEntries() {
        isCacheValid = false;
        _Collection = getEntries();
    }

    //Methods
    public void InvalidateCache() {
        this.isCacheValid = false;
    }
    public ArrayList<LogEntry> getEntries() {

        if(!isCacheValid) {
            _Collection = LogEntrySource.GetEntries(DiverProfile.getActiveProfile().getID());

            for(int i = 0 ; i < _Collection.size(); i++)
            {
                try {
                    LogEntry e = _Collection.get(i);

                    if(i == 0)
                        RDPCalculator.AssignPressureGroupForDive(e);
                    else
                        RDPCalculator.AssignPressureGroupForDive(_Collection.get(i - 1), e);
                }
                catch(Exception e) {
                    System.out.println(e.getMessage());
                }
            }
        }
        return _Collection;
    }

    public int getNextDiveNumber() {
        //return the next number, so if the max diveNumber is 100, return 101
        InvalidateCache();

        if(this.getEntries().isEmpty())
            return 1;

        return Collections.max(_Collection).getDiveNumber() + 1;
    }

    public Period getCumulativeTime() {

        Period p = new Period();
        for(LogEntry e : getEntries())
            p = p.plusMinutes(e.getDiveDuration());

        return p;
    }
    public int getCumulativeDives() {
        return getEntries().size();
    }

    public LogEntry getCurrentLog() { return Current; }
    public LogEntry CreateNew() {
        //creates a new Log Entry
        this.Current = new LogEntry(this.getNextDiveNumber(), new LocalDate(Toolbelt.Toolkit.getToday()));
        return getCurrent();
    }

    private void InternalAssignPressureGroupToCurrent() {
        if(_Collection.size() == 0) {
            //this is the first dive
            try {
                RDPCalculator.AssignPressureGroupForDive(getCurrent());
            }
            catch(Exception e) {
                //something went wrong?
            }

            return;
        }

        //There is a previous dive
        try {
            RDPCalculator.AssignPressureGroupForDive(_Collection.get(0), getCurrent());
        }
        catch(Exception e) {
            //something went wrong
        }

        return;
    }
    public static void AssignPressureGroupToCurrent() {
        getInstance().InternalAssignPressureGroupToCurrent();
    }
}
